package cn.hrc.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration //将SecurityConfig创建对象放入ioc容器
@EnableWebSecurity
//请求先到这里 SecurityConfig 过滤一下 才会到控制器
public class SecurityConfig {
    @Autowired
    RedisTemplate redisTemplate;
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public SecurityConfig() {
        System.out.println("将SecurityConfig创建对象放入ioc容器");
    }
    /*获取认证管理器 ,比对密码
    * 1. 主动调用 loadUserByUsername(...) 访问 t_user
    * 2.主动对比账号密码
    *     - 成功 successfulAuthentication
    *     - 失败 unsuccessfulAuthentication*/
    @Autowired
    AuthenticationConfiguration authenticationConfig;
    //获取认证管理器的配置类， 再去获取认证管理器
    @Bean
    AuthenticationManager authenticationManager() throws Exception {
        return authenticationConfig.getAuthenticationManager();
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    //用户信息,内存用户信息
    //UserDetailsService User 用户 Details(具体信息)  Service服务
//    @Bean
//    UserDetailsService userDetailsService(){
//        UserDetails user = null;
//        return user;
//    }
    //127.0.0.1:8080
    @Bean //http.build() 返回值装配到 IOC容器
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        logger.info("开始拦截......");
        http.authorizeRequests()//拦截请求
                .antMatchers("/api/login")// 登录
                .permitAll()// 放行
                .antMatchers("/go2login")// 登录页面
                .permitAll()// 放行
                .antMatchers("/",
                        "/static/**",
                        "/*.html",
                        "/js/**",
                        "/css/**",
                        "/img/**")
                .permitAll()//
                .antMatchers("/api/public/**")
                .permitAll()//公共
                .antMatchers("/api/user")// 登录成功可以访问
                .permitAll()//用户
                .antMatchers("/api/adm/**")
                .hasAuthority("adm") //管理员
                .anyRequest().authenticated()   //authened 已经登录成功后才能访问
                .and()
                .formLogin()   //  /login
//                .loginPage("/go2login")
//                .loginProcessingUrl("/login")
                .permitAll()   //  无需登录可以访问（permit 允许）
                .and()
                .csrf().disable()
                .sessionManagement()//不走 session 我要走自己方式【Token】
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilter(
                        new JwtLoginFilter(redisTemplate,
                                authenticationConfig.getAuthenticationManager()
                        ))
                .addFilter(
                        new JwtAuthenFilter(redisTemplate,
                                authenticationConfig.getAuthenticationManager()
                        ))
                .exceptionHandling().authenticationEntryPoint(
                        new JwtAuthEntryPoint()
                );
        logger.info("结束拦截......");
        return http.build();
    }
}
